﻿using System;
using System.Collections.Generic;
using System.Text;
using ITAP.Core.Modelling.Primitives;
using System.Drawing;
using System.Collections;
using ITAP.ShprossesBuilder.Modelling.Components.Constraints;
using ITAP.ShprossesBuilder.Calculations;
using ITAP.Core.Modelling;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Modelling.Components
{
    [Serializable]
    public class SpacerElement : IEndedComponent
    {
        private bool uniqueIdsEnabled = true;

        public bool UniqueIdsEnabled
        {
            get { return uniqueIdsEnabled; }
            set { uniqueIdsEnabled = value; }
        }

        private List<int> acceptedUniqueIdsToConnect;

        public List<int> AcceptedUniqueIdsToConnect
        {
            get { return acceptedUniqueIdsToConnect; }
            set { acceptedUniqueIdsToConnect = value; }
        }

        private int uniqueId;

        public int UniqueId
        {
            get { return uniqueId; }
        }

        private bool inaccessibleFromMaterials = false;

        public bool InaccessibleFromMaterials
        {
            get { return inaccessibleFromMaterials; }
            set { inaccessibleFromMaterials = value; }
        }


        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private int serialNumber;

        public int SerialNumber
        {
            get { return serialNumber; }
            set { serialNumber = value; }
        }

        private bool autoConnectComponentsInTolerance = true;

        public bool AutoConnectComponentsInTolerance
        {
            get { return autoConnectComponentsInTolerance; }
            set { autoConnectComponentsInTolerance = value; }
        }

        private double tolerance = 6;
        private List<IComponent> componentsInTolerance;

        public List<IComponent> ComponentsInTolerance
        {
            get { return componentsInTolerance; }
        }

        private bool isUpdateRequired = false;

        private List<Type> connectPriorityForEnds;

        private IComponent parent;
        private ConnectionInfo acceptedComponentTypesToConnect;
        private bool errorDebug = false;

        public bool ErrorDebug
        {
            get { return errorDebug; }
            set { errorDebug = value; }
        }

        private string article;
        private List<Type> criticalConstraintTypes;
        private List<IConstraint> constraints;
        private List<IComponent> innerComponents;
        private List<IComponent> connectedComponents;

        public Angle StartCutAngle
        {
            get { return ((IWidePrimitive)this.Primitives[0]).StartCutAngle; }
            set { ((IWidePrimitive)this.Primitives[0]).StartCutAngle = value; }
        }

        public Angle EndCutAngle
        {
            get { return ((IWidePrimitive)this.Primitives[0]).EndCutAngle; }
            set { ((IWidePrimitive)this.Primitives[0]).EndCutAngle = value; }
        }

        public ModelPoint StartPoint
        {
            get { return ((IEndedPrimitive)this.primitives[0]).StartPoint; }
            set 
            { 
                ((IEndedPrimitive)this.primitives[0]).StartPoint = value;
            //    this.primitives[0].Update();
            }
        }

        public ModelPoint EndPoint
        {
            get { return ((IEndedPrimitive)this.primitives[0]).EndPoint; }
            set 
            { 
                ((IEndedPrimitive)this.primitives[0]).EndPoint = value;
           //     this.primitives[0].Update();
            }
        }

        private IComponent startConnectedComponent;

        public IComponent StartConnectedComponent
        {
            get { return startConnectedComponent; }
            set { startConnectedComponent = value; }
        }
        private IComponent endConnectedComponent;

        public IComponent EndConnectedComponent
        {
            get { return endConnectedComponent; }
            set { endConnectedComponent = value; }
        }

        private bool isChangedSinceLastUpdate = true;
        private ModelPoint position;
        private List<IPrimitive> primitives;

        #region IComponent Members

        public List<IComponent> ConnectedComponents
        {
            get
            {
                return connectedComponents;
            }
        }

        public double Tolerance
        {
            get
            {
                return tolerance;
            }
            set
            {
                tolerance = value;
            }
        }

        public bool IsUpdateRequired
        {
            get { return isUpdateRequired; }
            set { isUpdateRequired = value; }
        }

        public List<IPrimitive> Primitives
        {
            get
            {
                return primitives;
            }
            set
            {
                primitives = value;
            }
        }

        public SpacerElement()
        {
            innerComponents = new List<IComponent>();
            primitives = new List<IPrimitive>();
            position = new ModelPoint(0, 0);
            constraints = new List<IConstraint>();
            connectedComponents = new List<IComponent>();
            criticalConstraintTypes = new List<Type>();
            acceptedComponentTypesToConnect = new ConnectionInfo();
            this.componentsInTolerance = new List<IComponent>();
        }

        public IComponent ConnectTo(IComponent component)
        {
            IComponent componentToConnect = null;
            List<IComponent> validComponentsToConnect = new List<IComponent>();
            this.RecursiveConnectTo(component, validComponentsToConnect);
            double distance = double.MaxValue;
            foreach (IComponent validComponent in validComponentsToConnect)
            {
                double currentDistance = ModelCalculations.GetDistance(this.Position, validComponent.Position);
                if (currentDistance < distance)
                {
                    distance = currentDistance;
                    componentToConnect = validComponent;
                }
            }
            if (!this.connectedComponents.Contains(componentToConnect))
            {
                double startPointDistance = ModelCalculations.GetDistance(this.StartPoint, componentToConnect.Position);
                double endPointDistance = ModelCalculations.GetDistance(this.EndPoint, componentToConnect.Position);
                if (startPointDistance < endPointDistance)
                {
                    if (this.startConnectedComponent != null)
                        return null;
                    this.startConnectedComponent = componentToConnect;
                }
                else
                {
                    if (this.endConnectedComponent != null)
                        return null;
                    this.endConnectedComponent = componentToConnect;
                }
                this.connectedComponents.Add(componentToConnect);
                return this;
            }
            else
                return null;
        }

        private void RecursiveConnectTo(IComponent component, List<IComponent> connectedComponents)
        {
            if (acceptedComponentTypesToConnect.Contains(component.GetType()))
            {
                //if (!this.connectedComponents.Contains(component))
                    connectedComponents.Add(component);

                return;
            }
            foreach (IComponent innerComponent in component.InnerComponents)
            {
                this.RecursiveConnectTo(innerComponent, connectedComponents);
            }
        }

        public IComponent DisconnectFrom(IComponent component)
        {
            if (this.connectedComponents.Remove(component))
            {
                if (component == this.startConnectedComponent)
                    startConnectedComponent = null;
                else if (component == this.endConnectedComponent)
                    this.endConnectedComponent = null;

                return this;
            }
            else
                return null;
        }

        public void Update()
        {
            //if (this.isUpdateRequired == false)
            //    return;

            foreach (IConstraint constraint in this.constraints)
            {
                bool isChecked = false;
                try
                {
                    isChecked = constraint.Check(this);
                }
                catch (Exception ex)
                {
                    FatalErrorEventArgs e = new FatalErrorEventArgs();
                    e.FatalConstraint = constraint;
                    e.FatalException = ex;
                    this.FatalModelError.Invoke(this, e);
                    continue;
                }

                if (!isChecked)
                {
                    ComponentConstraintEventArgs e = new ComponentConstraintEventArgs(constraint);
                    this.BeforeFixingConstraint.Invoke(this, e);

                    //Logger.Write("    " + this.Name + " " + constraint.GetType().Name + " " + constraint.Action.ToString());
                    if (!e.CancelFixing)
                        constraint.Fix(this);

              //      this.isUpdateRequired = false;

                    this.AfterFixingConstraint.Invoke(this, e);

                }
            }
            this.isChangedSinceLastUpdate = false;
        }

        public void AcceptVisitor(IModelVisitor visitor)
        {
            visitor.Visit(this);
        }

        public bool IsInTolerance(ModelPoint point)
        {
            return this.Primitives[0].IsInTolerance(point, this.Tolerance);
        }

        #endregion

        #region IComponent Members


        public virtual ModelPoint Position
        {
            get
            {
                if (primitives.Count != 0)
                {
                    return this.primitives[0].GetPoint(0.5);
                }
                else
                    return null;
            }
        }

        #endregion

        #region IComponent Members


        public bool IsChangedSinceLastUpdate
        {
            get { return this.isChangedSinceLastUpdate; }
        }

        #endregion

        #region IComponent Members

        public List<IConstraint> Constraints
        {
            get
            {
                return constraints;
            }
        }

        public List<IComponent> InnerComponents
        {
            get { return innerComponents; }
        }

        #endregion

        #region IComponent Members


        public List<IComponent> GetComponentsByPoint(ModelPoint point, double tolerance)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IComponent Members


        public bool MoveTo(ModelPoint destination)
        {
            double xOffset = destination.X - this.Position.X;
            double yOffset = destination.Y - this.Position.Y;
            foreach (IPrimitive primitive in this.Primitives)
                primitive.MoveWithOffset(new ModelVector(xOffset, yOffset));

            this.isChangedSinceLastUpdate = true;

            return true;
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IComponent Members


        public bool MoveWithOffset(ModelVector offset)
        {
            foreach (IPrimitive primitive in this.primitives)
                primitive.MoveWithOffset(offset);
            return true;
        }

        #endregion

        #region IComponent Members

        public RectangleF BoundingBox
        {
            get 
            {
                return this.Primitives[0].BoundingBox;
            }
        }

        #endregion

        #region IComponent Members


        public bool Rotate(double angleOffset, ModelPoint rotateCenter)
        {
            foreach (IPrimitive primitive in this.primitives)
                primitive.Rotate(rotateCenter, angleOffset);

            return true;
        }

        #endregion

        #region IComponent Members


        public EndType GetComponentNearestEndType(IComponent component)
        {
            if (component is IEndedComponent)
            {
                IEndedComponent endedComponent = (IEndedComponent)component;
                double startPointStartPointDistance = ModelCalculations.GetDistance(this.StartPoint, endedComponent.StartPoint);
                double endPointStartPointDistance = ModelCalculations.GetDistance(this.EndPoint, endedComponent.StartPoint);
                double startPointEndPointDistance = ModelCalculations.GetDistance(this.StartPoint, endedComponent.EndPoint);
                double endPointEndPointDistance = ModelCalculations.GetDistance(this.EndPoint, endedComponent.EndPoint);
                List<double> distances = new List<double>();
                distances.Add(startPointStartPointDistance);
                distances.Add(endPointStartPointDistance);
                distances.Add(startPointEndPointDistance);
                distances.Add(endPointEndPointDistance);
                distances.Sort();

                if (Math.Abs((distances[0] - startPointStartPointDistance)) < ModelPoint.Tolerance && Math.Abs(distances[0] - startPointEndPointDistance) < ModelPoint.Tolerance)
                    return EndType.Both;

                if (distances[0] == startPointStartPointDistance || distances[0] == startPointEndPointDistance)
                    return EndType.Start;

                if (distances[0] == endPointEndPointDistance || distances[0] == endPointStartPointDistance)
                    return EndType.End;

                return EndType.NotDefined;

            }
            else
            {
                double startPointDistance = ModelCalculations.GetDistance(this.StartPoint, component.Position);
                double endPointDistance = ModelCalculations.GetDistance(this.EndPoint, component.Position);
                if (startPointDistance < endPointDistance)
                    return EndType.Start;
                else if (Math.Abs(startPointDistance - endPointDistance) < ModelPoint.Tolerance)
                    return EndType.Both;
                else
                    return EndType.End;
            }
        }

        #endregion

        #region IComponent Members


        public List<Type> PreUpdatePriority
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        #region IComponent Members

        public bool CanConnect(IComponent component)
        {
            //if (ConnectionProvider.Connect(this, component))
            //    return false;


            //foreach (IConstraint constraint in this.Constraints)
            //    if (constraint is ConnectedComponentsTypeConstraint)
            //        if (constraint.Check(this) == false)
            //        {
            //            ConnectionProvider.Disconnect(this, component);
            //            return false;
            //        }

            //ConnectionProvider.Disconnect(this, component);
            return true;
        }

        #endregion

        #region IComponent Members


        public List<Type> PostUpdatePriority
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IComponent Members


        public IComponent Parent
        {
            get
            {
                return parent;
            }
            set
            {
                parent = value;
            }
        }

        #endregion

        #region IComponent Members


        public virtual bool CheckConstraints()
        {
            foreach (IConstraint constraint in this.constraints)
                if (!constraint.Check(this))
                    return false;

            return true;
        }

        #endregion

        #region IComponent Members


        public List<Type> CriticalConstraintTypes
        {
            get { return criticalConstraintTypes; }
        }



        public virtual bool CheckCriticalConstraints()
        {
            foreach (IConstraint constraint in this.constraints)
                if (this.criticalConstraintTypes.Contains(constraint.GetType()))
                    if (constraint.Check(this) == false)
                        return false;

            return true;
        }

        public virtual bool CheckAllConstraints()
        {
            if (!this.CheckConstraints())
                return false;

            foreach (IComponent innerComponent in this.InnerComponents)
                if (!innerComponent.CheckAllConstraints())
                    return false;

            return true;
        }

        public virtual bool CheckAllCriticalConstraints()
        {
            if (!this.CheckCriticalConstraints())
                return false;

            foreach (IComponent innerComponent in this.InnerComponents)
                if (!innerComponent.CheckAllCriticalConstraints())
                    return false;

            return true;
        }


        #endregion

        #region IComponent Members



        public bool EnableConstraintsFixing
        {
            get
            {
                foreach (IConstraint constraint in this.constraints)
                    if (constraint.Enabled == false)
                        return false;

                return true;
            }
            set
            {
                foreach (IConstraint constraint in this.constraints)
                    constraint.Enabled = value;
            }
        }

        public bool EnableAllConstraintsFixing
        {
            get
            {
                bool isEnabled = this.EnableConstraintsFixing;
                if (!isEnabled)
                    return false;

                foreach (IComponent component in this.innerComponents)
                    if (!component.EnableAllConstraintsFixing)
                        return false;

                return true;
            }
            set
            {
                this.EnableConstraintsFixing = value;

                foreach (IComponent component in this.innerComponents)
                    component.EnableAllConstraintsFixing = value;
            }
        }
        #endregion

        #region IComponent Members


        public string Article
        {
            get
            {
                return article;
            }
            set
            {
                article = value;
            }
        }

        #endregion

        #region IEndedComponent Members


        public IComponent ConnectTo(IComponent component, EndType endForConnect)
        {
            IComponent componentToConnect = null;
            List<IComponent> validComponentsToConnect = new List<IComponent>();
            this.RecursiveConnectTo(component, validComponentsToConnect);
            double distance = double.MaxValue;
            foreach (IComponent validComponent in validComponentsToConnect)
            {
                double currentDistance = double.MaxValue;
                if (endForConnect == EndType.Start)
                    currentDistance = ModelCalculations.GetDistance(this.StartPoint, validComponent.Position);
                else if (endForConnect == EndType.End)
                    currentDistance = ModelCalculations.GetDistance(this.EndPoint, validComponent.Position);

                if (currentDistance < distance)
                {
                    distance = currentDistance;
                    componentToConnect = validComponent;
                }
            }
            //if (!this.connectedComponents.Contains(componentToConnect))
            //{

                switch (endForConnect)
                {
                    case EndType.Start:
                        if (this.StartConnectedComponent == null)
                            this.StartConnectedComponent = componentToConnect;
                        else
                            return null;
                        break;
                    case EndType.End:
                        if (this.EndConnectedComponent == null)
                            this.EndConnectedComponent = componentToConnect;
                        else
                            return null;
                        break;
                    default:
                        return null;
                }
                this.connectedComponents.Add(componentToConnect);
                return this;
            //}
            //else
            //    return null;
        }

        #endregion

        #region IComponent Members


        public ConnectionInfo AcceptedComponentTypesToConnect
        {
            get { return acceptedComponentTypesToConnect; }
        }

        #endregion

        #region IComponent Members


        public IComponent ConnectToEnded(IEndedComponent endedComponent, EndType endToConnect)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public event ComponentConstraintEventDelegate BeforeFixingConstraint;

        public event ComponentConstraintEventDelegate AfterFixingConstraint;

        #endregion

        #region IComponent Members


        private void GetAllInnerComponents(IComponent component, List<IComponent> innerComponents)
        {
            if (!innerComponents.Contains(component))
                innerComponents.Add(component);
            foreach (IComponent innerComponent in component.InnerComponents)
                this.GetAllInnerComponents(innerComponent, innerComponents);
        }

        public List<IComponent> AllInnerComponents
        {
            get
            {
                List<IComponent> allInnerComponents = new List<IComponent>();
                foreach (IComponent innerComponent in this.innerComponents)
                    this.GetAllInnerComponents(innerComponent, allInnerComponents);
                return allInnerComponents;
            }
        }

        #endregion

        #region IEndedComponent Members


        public ModelPoint[] Intersect(IEndedComponent component)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEndedComponent Members


        public List<Type> ConnectPriorityForEnds
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IEndedComponent Members


        public void MoveStartPointTo(ModelPoint destination)
        {
            throw new NotImplementedException();
        }

        public void MoveEndPointTo(ModelPoint destination)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public bool IsConnected(IComponent other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEndedComponent Members


        public double Width
        {
            get
            {
                return ((IWidePrimitive)this.Primitives[0]).Width;
            }
            set
            {
                ((IWidePrimitive)this.primitives[0]).Width = value;
            }
        }

        #endregion

        #region IComponent Members

        public void BeforeFixingInnerComponentConstraintEvent(IComponent sender, ComponentConstraintEventArgs e)
        {
            if (this.BeforeFixingConstraint != null)
                this.BeforeFixingConstraint.Invoke(sender, e);
        }

        public void AfterFixingInnerComponentConstraintEvent(IComponent sender, ComponentConstraintEventArgs e)
        {
            if (this.AfterFixingConstraint != null)
                this.AfterFixingConstraint.Invoke(sender, e);
        }


        #endregion

        #region IComponent Members


        public void AddInnerComponent(IComponent component)
        {
            if (!this.innerComponents.Contains(component))
            {
                this.innerComponents.Add(component);
                component.Parent = this;
                component.BeforeFixingConstraint += new ComponentConstraintEventDelegate(this.BeforeFixingInnerComponentConstraintEvent);
                component.AfterFixingConstraint += new ComponentConstraintEventDelegate(this.AfterFixingInnerComponentConstraintEvent);
                component.FatalModelError += new FatalModelErrorDelegate(this.FatalModelErrorEvent);
            }
        }

        public bool RemoveInnerComponent(IComponent component)
        {
            if (this.innerComponents.Remove(component))
            {
                component.Parent = null;
                component.BeforeFixingConstraint -= this.BeforeFixingInnerComponentConstraintEvent;
                component.AfterFixingConstraint -= this.AfterFixingInnerComponentConstraintEvent;
                component.FatalModelError -= this.FatalModelErrorEvent;
                return true;
            }
            else
                return false;
        }

        #endregion

        #region IEndedComponent Members


        public double Height
        {
            get
            {
                return ((IWidePrimitive)this.primitives[0]).Height;
            }
            set
            {
                if (this.Height != 0 && !SimpleEqualProvider.IsEqual(value, 0, 0.0001))
                {
                    ((IWidePrimitive)this.Primitives[0]).Height = value;
                }
                else
                {
                    double _width = this.Width;
                    ModelPoint _startPoint = (ModelPoint)this.StartPoint.Clone();
                    ModelPoint _endPoint = (ModelPoint)this.EndPoint.Clone();
                    Angle _startCutAngle = (Angle)this.StartCutAngle.Clone();
                    Angle _endCutAngle = (Angle)this.EndCutAngle.Clone();

                    this.Primitives.Clear();
                    if (SimpleEqualProvider.IsEqual(value, 0, 0.001))
                        this.Primitives.Add(PrimitiveFactory.CreateLinePrimitive(_width, _startPoint, _endPoint, _startCutAngle, _startCutAngle));
                    else
                        this.Primitives.Add(PrimitiveFactory.CreateCirclePrimitive(_width, _startPoint, _endPoint, value, _startCutAngle, _endCutAngle));
                }
            }
        }

        #endregion

        #region IComponent Members


        public event FatalModelErrorDelegate FatalModelError;

        #endregion

        #region IComponent Members

        public void FatalModelErrorEvent(IComponent sender, FatalErrorEventArgs e)
        {
            if (this.FatalModelError != null)
                this.FatalModelError.Invoke(sender, e);
        }

        #endregion

        #region IComponent Members


        public ModelPoint GetNearestPointOnComponent(ModelPoint point, StickConnectionType stickType, out StickConnectionType sticked, ProjectionType projectionType)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public bool Selected
        {
            get
            {
                return false;
            }
            set
            {               
            }
        }

        #endregion

        #region IComponent Members


        public bool IsPointInComponent(ModelPoint point)
        {
            return false;
        }

        #endregion

        #region IModelVisitor Members

        public void Visit(Model model)
        {
          //  throw new NotImplementedException();
        }

        public void Visit(Connector connector)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(Shpross shpross)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(Spacer spacer)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(ShprossConnectorStub stub)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(ShprossConnector shprossConnector)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(SpacerElement spacerElement)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(SpacerConnector spacerConnector)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(ModelCell modelCell)
        {
        //    throw new NotImplementedException();
        }

        public void Visit(ModelContainer modelContainer)
        {
        //    throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members

        public void DisconnectComponentsInTolerance()
        {
            throw new NotImplementedException();
        }

        #endregion

        public void DisconnectFromAll()
        {
            List<IComponent> componentsToDisconnect = new List<IComponent>();
            foreach (IComponent connectedComponent in this.ConnectedComponents)
            {
                componentsToDisconnect.Add(connectedComponent);
            }
            foreach (IComponent connectedComponent in componentsToDisconnect)
            {
                ConnectionProvider.Disconnect(this, connectedComponent);
            }
        }


        #region IComponent Members


        public ModelPoint GetNearestPointOnComponent(ModelPoint point, ModelPoint measurePoint, StickConnectionType stickType, out StickConnectionType sticked, ProjectionType projectionType)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(StickConnector stickConnector)
        {
            //throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public void MoveToZeroPoint()
        {
            throw new NotImplementedException();
        }

        public void MoveToZeroXPoint()
        {
            throw new NotImplementedException();
        }

        public void MoveToZeroYPoint()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(SnapOnCap snapOnCap)
        {
            //throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public bool SelectByPoint(ModelPoint point)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public void Rotate(double angleOffset)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEndedComponent Members


        public double Length
        {
            get
            {
                return this.primitives[0].Length;
            }
            set
            {
                
            }
        }

        #endregion

        #region IComponent Members


        public ModelPoint GetNearestPointOnComponent(ModelPoint point, StickConnectionType stickType, out StickConnectionType sticked, out IComponent innerComponent, ProjectionType projectionType)
        {
            throw new NotImplementedException();
        }

        public ModelPoint GetNearestPointOnComponent(ModelPoint point, ModelPoint measurePoint, StickConnectionType stickType, out StickConnectionType sticked, out IComponent innerComponent, ProjectionType projectionType)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEndedComponent Members


        public void MoveStartPointTo(ModelPoint destination, RectangleF boundingRectangle, bool allowOutOfRectangleForOneEnd)
        {
           
        }

        public void MoveEndPointTo(ModelPoint destination, RectangleF boundingRectangle, bool allowOutOfRectangleForOneEnd)
        {
          
        }

        #endregion

        #region IComponent Members


        public bool MoveTo(ModelPoint destination, RectangleF boundingRectangle)
        {
            throw new NotImplementedException();
        }

        public bool MoveWithOffset(ModelVector offset, RectangleF boundingRectangle)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEndedComponent Members


        public void SetHeight(double height, RectangleF boundingRectangle)
        {
            throw new NotImplementedException();
        }

        #endregion

        public void RemoveAllInnerComponents()
        {
            foreach (IComponent innerComponent in this.innerComponents)
            {
                innerComponent.RemoveAllInnerComponents();
                this.RemoveInnerComponent(innerComponent);
            }
        }


        #region IComponent Members


        public bool Rotate(double angleOffset, ModelPoint rotateCenter, RectangleF boundingRectangle)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public bool Rotate(double angleOffset, RectangleF boundingRectangle)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public bool IsInTolerance(ModelPoint point, double tolerance)
        {
            return this.primitives[0].IsInTolerance(point, tolerance);
        }

        #endregion

        #region IEndedComponent Members


        public EndType IsConnectedToEnd(IComponent component)
        {
            if (this.startConnectedComponent == component && this.endConnectedComponent != component)
                return EndType.Start;
            if (this.endConnectedComponent == component && this.startConnectedComponent != component)
                return EndType.End;
            if (this.endConnectedComponent == component && this.startConnectedComponent == component)
                return EndType.Both;
            return EndType.NotDefined;
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(ShprossEndToEndConnector endToEndConnector)
        {
            //throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(ShprossChain shprossChain)
        {
   //         throw new NotImplementedException();
        }

        #endregion

        #region IComponent Members


        public IComponent Copy()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(SpacerContainer spacerContainer)
        {
       //     throw new NotImplementedException();
        }

        #endregion

        #region IModelVisitor Members


        public void Visit(CrossConnector crossConnector)
        {
    //        throw new NotImplementedException();
        }

        #endregion

    }
}
